/**
 * @UiTooltip.cpp
 * Copyright 2013 (C) FatalEror / Dean Bahari
 * 
 * UiPack is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * See LICENSE file in main folder for more information.
 */

#include "UiCommon.hpp"
#include "UiApp.hpp"
#include "UiBase.hpp"
#include "UiResource.hpp"
#include "UiTooltip.hpp"

UiTooltip::UiTooltip(UiBase *owner, const wchar_t *text)
{
	SetWindowLongPtr(this->getHandle(), GWLP_USERDATA, NULL);
	DestroyWindow(this->getHandle());
	this->setHandle(CreateWindow(L"UiTooltip", text, WS_CLIPCHILDREN | WS_CLIPSIBLINGS, CW_USEDEFAULT, CW_USEDEFAULT, 1, 1, NULL, 0, GetModuleHandle(0), this));

	SetWindowLong(this->getHandle(), GWL_STYLE, (GetWindowLong(this->getHandle(), GWL_STYLE) & (~WS_OVERLAPPEDWINDOW)));
	SetWindowLong(this->getHandle(), GWL_EXSTYLE, WS_EX_TOOLWINDOW);
	SetWindowPos(this->getHandle(), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOREDRAW);

	mOwner = owner;
	this->setSize(1, 1);	
	this->setText(text);
}

void UiTooltip::setText(const wchar_t *text)
{
	mText = text;

	Gdiplus::RectF rect;
	Gdiplus::Graphics graph(this->getHandle());
	graph.MeasureString(mText.c_str(), -1, &Gdiplus::Font(UiApp::getResource()->getFont(), 10, Gdiplus::FontStyleRegular, Gdiplus::UnitPixel), Gdiplus::PointF(0, 0), &rect);
	this->setSize(static_cast<int>(rect.Width) + 8, static_cast<int>(rect.Height) + 4);
}

void UiTooltip::show()
{
	RECT rc;
	GetWindowRect(mOwner->getHandle(), &rc);
	this->setPosition(static_cast<int>(rc.right + rc.left - this->getWidth()) / 2, rc.bottom + 3);
	ShowWindow(this->getHandle(), SW_SHOW);
	UpdateWindow(this->getHandle());
}

void UiTooltip::hide()
{
	ShowWindow(this->getHandle(), SW_HIDE);
}

LRESULT CALLBACK UiTooltip::handleCustomProc(UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch (msg) {
	case WM_NCPAINT:
	{
		HDC hDC = GetWindowDC(this->getHandle());

		Gdiplus::Graphics graph(hDC);

		graph.FillRectangle(UiApp::getResource()->getBrush(UiResource::UI_BRUSH_TOOLTIP), 0, 0, this->getWidth(), this->getHeight());
		graph.DrawRectangle(UiApp::getResource()->getPen(UiResource::UI_PEN_BORDER), 0, 0, this->getWidth() - 1, this->getHeight() - 1);

		Gdiplus::GraphicsPath path;
		Gdiplus::StringFormat sf;
		sf.SetAlignment(Gdiplus::StringAlignmentCenter);
		path.AddString(mText.c_str(), -1, UiApp::getResource()->getFont(), Gdiplus::FontStyleRegular, 10, Gdiplus::PointF(this->getWidth() / 2.0f, 1.0f), &sf);
		graph.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
		graph.FillPath(UiApp::getResource()->getBrush(UiResource::UI_BRUSH_TEXT), &path);
		graph.SetSmoothingMode(Gdiplus::SmoothingModeNone);

		ReleaseDC(this->getHandle(), hDC);
	} break;
	case WM_NCACTIVATE:
	case WM_ERASEBKGND:
		return 1;
	case WM_TIMER:
	default:
		return DefWindowProc(this->getHandle(), msg, wParam, lParam);
	}
	return 0;
}